/*  ----------------------------------------------------------------------------
 *  Arello Mobile
 *  Fast 3d Engine
 *  ----------------------------------------------------------------------------
 * Except where otherwise noted, this work is licensed under
 * http://creativecommons.org/licenses/by/3.0
 */

#include "SoundListener.h"
#include <noise/Manager.h>
#include <noise/hard/Hardware.h>
//#include "SoundEnviroment.h"

namespace liba
{
namespace lib3d
{
namespace node
{

WowPtr<Node> SoundListener::active_listener( 0 );

const Atom SoundListener::node_name("SoundListener");

SoundListener::SoundListener(const Atom & name, Node * parent ):
	liba::lib3d::node::Node( name, parent ),
	last_pos( 0,0,0 )
//	distance_factor(1)
{}

void SoundListener::update_position(double delta_time)
{
	Vector pos = GetGlobalMatrix().shift();
	Vector speed = (delta_time == 0) ? Vector(0,0,0) : Vector((pos - last_pos)/delta_time);
	last_pos = pos;
	Vector up = Vector(0,1,0) * GetGlobalMatrix();
	up.normalize();
	Vector front = Vector(0,0,-1) * GetGlobalMatrix();
	front.normalize();

	if( this == active_listener )
	{
		noise::Manager::get_hardware()->FindProperty<Vector>(noise::hard::Hardware::listener_position_name)->Set(pos);
		noise::Manager::get_hardware()->FindProperty<Vector>(noise::hard::Hardware::listener_speed_name)->Set(speed);
		noise::Manager::get_hardware()->FindProperty<Vector>(noise::hard::Hardware::listener_front_name)->Set(front);
		noise::Manager::get_hardware()->FindProperty<Vector>(noise::hard::Hardware::listener_up_name)->Set(up);
	}
}

void SoundListener::set_active_listener( Node * listener )
{
	active_listener = listener;
//	if( active_listener )
//		active_listener->update_position(1);
}

bool SoundListener::is_listening( Node * sound )
{
	if( !active_listener )
		return false; // all 3d-sounds cannot exist without listener
	return sound->GetRoot() == active_listener->GetRoot();
}

void SoundListener::LifeCycle(time_float delta_time)
{
	update_position(delta_time);

/*	if( !is_listening( get_root() ) || !this->get_visibility() )return;

	lib3d::Vector pos = get_full_matrix().shift();
	lib3d::Vector velocity = pos - last_pos;
	sound::Manager::mixer()->get_listener()->set_position( pos );
	sound::Manager::mixer()->get_listener()->set_velocity( velocity );
	last_pos = pos;
	Vector up = Vector(0,1,0) * get_full_matrix();
	Vector front = Vector(0,0,1) * get_full_matrix();
	sound::Manager::mixer()->get_listener()->set_orientation( front, up );
	sound::Manager::mixer()->get_listener()->set_distance_factor( distance_factor );
	SoundEnviroment::select_enviroment( this );*/
}

bool SoundListener::on_attribute( xml::Provider * prov, const std::string & name, const std::string & value )
{
///	if(name == "DistanceFactor")
///		return converter::convert(value, &distance_factor);
	return Node::on_attribute(prov, name, value);
}

} // node
} // namespace lib3d
} // namespace liba

